#include "NetworkClient.h"
#include "Logger.h"
#include "SeanNetwork.h"

namespace SeanNetwork {

NetworkClient::NetworkClient(ProtocolType protocol)
    : m_NetworkManager(nullptr),
      m_Port(0),
      m_AutoReconnect(false),
      m_ReconnectMaxAttempts(5),
      m_ReconnectInitialDelay(1000),
      m_ReconnectAttempts(0),
      m_ReconnectTimer(nullptr),
      m_ReconnectWork(nullptr),
      m_ReconnectThreadRunning(false),
      m_ProtocolType(protocol),
      m_DeltaTime(0.0f) {
    // Nothing else to initialize
    LOG_DEBUG("NetworkClient created with protocol: " + 
              std::string(protocol == ProtocolType::TCP ? "TCP" : "KCP"));
}

NetworkClient::~NetworkClient() {
    // 先调用Stop确保所有资源被正确清理
    Stop();
}

bool NetworkClient::Initialize(const NetworkConfig& config) {
    /* 功能：初始化客户端
       参数：config-网络配置
       返回：初始化是否成功 */
    m_NetworkManager = std::make_unique<NetworkManager>();
    if (!m_NetworkManager->Initialize(config)) {
        m_NetworkManager.reset();
        return false;
    }
    
    // 设置回调
    m_NetworkManager->SetMessageCallback([this](std::shared_ptr<NetworkMessage> message) {
        HandleMessage(message);
    });
    
    m_NetworkManager->SetConnectionCallback([this](ConnectionState state, const std::string& reason) {
        HandleConnectionState(state, reason);
    });
    
    return true;
}

bool NetworkClient::Connect(const std::string& host, uint16_t port) {
    /* 功能：连接到服务器
       参数：host-服务器地址，port-服务器端口
       返回：连接操作是否成功启动 */
    if (!m_NetworkManager) {
        return false;
    }
    
    m_Host = host;
    m_Port = port;
    m_ReconnectAttempts = 0;
    
    // 启动连接
    bool connectionStarted = m_NetworkManager->Connect(host, port);
    
    // 如果连接不成功或者期望在服务器不存在时等待，启用自动重连
    if (!connectionStarted) {
        // 确保自动重连已启用
        if (!m_AutoReconnect) {
            SetAutoReconnect(true);
        }
        
        // 立即开始重连流程
        StartReconnect();
        
        // 返回true表示重连流程已经启动
        return true;
    }
    
    return connectionStarted;
}

void NetworkClient::Disconnect() {
    /* 功能：断开连接 */
    if (m_NetworkManager) {
        m_NetworkManager->Disconnect();
    }
    
    StopReconnect();
}

bool NetworkClient::SendMsg(std::shared_ptr<NetworkMessage> message) {
    /* 功能：发送消息
       参数：message-要发送的消息
       返回：发送操作是否成功启动 */
    if (!m_NetworkManager) {
        return false;
    }
    
    return m_NetworkManager->SendMsg(message);
}

std::shared_ptr<NetworkMessage> NetworkClient::CreateMessage(uint32_t messageId, MessagePriority priority) {
    /* 功能：创建新消息
       参数：messageId-消息ID，priority-消息优先级
       返回：创建的消息对象 */
    auto message = std::make_shared<NetworkMessage>(messageId, priority);
    return message;
}

void NetworkClient::RegisterMessageHandler(uint32_t messageId, std::function<void(std::shared_ptr<NetworkMessage>)> handler) {
    /* 功能：注册消息处理回调
       参数：messageId-消息ID，handler-处理回调 */
    if (handler) {
        m_MessageHandlers[messageId] = handler;
    }
    else {
        auto it = m_MessageHandlers.find(messageId);
        if (it != m_MessageHandlers.end()) {
            m_MessageHandlers.erase(it);
        }
    }
}

void NetworkClient::SetConnectionCallback(std::function<void(ConnectionState, const std::string&)> callback) {
    /* 功能：设置连接状态回调
       参数：callback-状态回调函数 */
    m_ConnectionCallback = callback;
}

ConnectionState NetworkClient::GetConnectionState() const {
    /* 功能：获取连接状态
       返回：当前连接状态 */
    if (!m_NetworkManager) {
        return ConnectionState::Disconnected;
    }
    
    return m_NetworkManager->GetConnectionState();
}

ChannelType NetworkClient::GetCurrentChannelType() const {
    /* 功能：获取当前通道类型
       返回：当前使用的通道类型 */
    if (!m_NetworkManager) {
        return ChannelType::KCP;
    }
    
    return m_NetworkManager->GetCurrentChannelType();
}

NetworkStats NetworkClient::GetNetworkStats() const {
    /* 功能：获取网络统计信息
       返回：当前网络统计 */
    if (!m_NetworkManager) {
        return NetworkStats();
    }
    
    return m_NetworkManager->GetNetworkStats();
}

bool NetworkClient::SwitchChannel(ChannelType channelType) {
    /* 功能：手动切换通道
       参数：channelType-目标通道类型
       返回：切换是否成功 */
    if (!m_NetworkManager) {
        return false;
    }
    
    return m_NetworkManager->SwitchChannel(channelType);
}

bool NetworkClient::Start() {
    /* 功能：启动客户端
       返回：启动是否成功 */
    if (!m_NetworkManager) {
        return false;
    }
    
    // 启动重连线程
    if (m_AutoReconnect) {
        // 确保先停止之前可能运行的重连线程
        StopReconnect();
        
        // 重置IO上下文
        m_ReconnectIoContext.restart();
        
        // 创建新的work对象
        m_ReconnectWork = std::make_unique<asio::io_context::work>(m_ReconnectIoContext);
        m_ReconnectThreadRunning = true;
        
        try {
            // 使用try-catch来捕获线程创建可能的异常
            m_ReconnectThread = std::thread([this]() {
                try {
                    this->ReconnectThreadFunc();
                }
                catch (const std::exception& e) {
                    // 线程内部异常处理
                    m_ReconnectThreadRunning = false;
                }
            });
        }
        catch (const std::exception&) {
            // 线程创建失败
            m_ReconnectThreadRunning = false;
            m_ReconnectWork.reset();
            return m_NetworkManager->Start(); // 仍然启动网络管理器，但没有重连线程
        }
    }
    
    return m_NetworkManager->Start();
}

void NetworkClient::Stop() {
    /* 功能：停止客户端 */
    // 先停止重连功能
    StopReconnect();
    
    // 然后停止网络管理器
    if (m_NetworkManager) {
        m_NetworkManager->Stop();
    }
    
    // 重置重连尝试次数
    m_ReconnectAttempts = 0;
}

void NetworkClient::SetAutoReconnect(bool enable, uint32_t maxAttempts, uint32_t initialDelayMs) {
    /* 功能：设置自动重连
       参数：enable-是否启用，maxAttempts-最大尝试次数，initialDelayMs-初始延迟 */
    // 如果状态没有变化，不需要重新创建线程
    if (m_AutoReconnect == enable) {
        // 只更新参数
        if (maxAttempts > 0) {
            m_ReconnectMaxAttempts = maxAttempts;
        }
        
        if (initialDelayMs > 0) {
            m_ReconnectInitialDelay = initialDelayMs;
        }
        return;
    }
    
    m_AutoReconnect = enable;
    
    if (maxAttempts > 0) {
        m_ReconnectMaxAttempts = maxAttempts;
    }
    
    if (initialDelayMs > 0) {
        m_ReconnectInitialDelay = initialDelayMs;
    }
    
    if (enable && !m_ReconnectThreadRunning) {
        // 先确保之前的线程已经停止
        StopReconnect();
        
        // 重置IO上下文
        m_ReconnectIoContext.restart();
        
        // 启动重连线程
        m_ReconnectWork = std::make_unique<asio::io_context::work>(m_ReconnectIoContext);
        m_ReconnectThreadRunning = true;
        
        try {
            m_ReconnectThread = std::thread([this]() {
                try {
                    this->ReconnectThreadFunc();
                }
                catch (const std::exception& e) {
                    // 线程内部异常处理
                    m_ReconnectThreadRunning = false;
                }
            });
        }
        catch (const std::exception&) {
            // 线程创建失败
            m_ReconnectThreadRunning = false;
            m_ReconnectWork.reset();
        }
    }
    else if (!enable && m_ReconnectThreadRunning) {
        StopReconnect();
    }
}

void NetworkClient::HandleMessage(std::shared_ptr<NetworkMessage> message) {
    /* 功能：处理接收到的消息
       参数：message-接收到的消息 */
    if (!message) {
        return;
    }
    
    uint32_t messageId = message->GetHeader().MessageId;
    
    // 查找对应的消息处理器
    auto it = m_MessageHandlers.find(messageId);
    if (it != m_MessageHandlers.end() && it->second) {
        it->second(message);
    }
}

void NetworkClient::HandleConnectionState(ConnectionState state, const std::string& reason) {
    /* 功能：处理连接状态变更
       参数：state-新状态，reason-状态变更原因 */
    
    // 根据状态处理重连逻辑
    if (state == ConnectionState::Disconnected || state == ConnectionState::Failed) {
        if (m_AutoReconnect) {
            // 更新状态为重连中，并通知用户
            std::string waitMessage = "Waiting for server...";
            if (m_ReconnectMaxAttempts > 0) {
                waitMessage += " (Attempt " + std::to_string(m_ReconnectAttempts + 1) + 
                              " of " + std::to_string(m_ReconnectMaxAttempts) + ")";
            }
            
            // 执行用户回调，通知正在等待服务器
            if (m_ConnectionCallback) {
                m_ConnectionCallback(ConnectionState::Reconnecting, waitMessage);
            }
            
            StartReconnect();
        } else {
            // 执行用户回调
            if (m_ConnectionCallback) {
                m_ConnectionCallback(state, reason);
            }
        }
    }
    else if (state == ConnectionState::Connected) {
        // 连接成功，重置重连计数
        m_ReconnectAttempts = 0;
        
        // 取消重连定时器
        if (m_ReconnectTimer) {
            asio::error_code ec;
            m_ReconnectTimer->cancel(ec);
        }
        
        // 执行用户回调
        if (m_ConnectionCallback) {
            m_ConnectionCallback(state, reason);
        }
    }
    else {
        // 其他状态直接通知用户
        if (m_ConnectionCallback) {
            m_ConnectionCallback(state, reason);
        }
    }
}

void NetworkClient::StartReconnect() {
    /* 功能：启动重连流程 */
    if (!m_AutoReconnect || m_Host.empty() || m_Port == 0) {
        return;
    }
    
    // 检查最大重连次数限制，但如果是初始连接等待服务器的情况，允许无限重试
    if (m_ReconnectMaxAttempts > 0 && m_ReconnectAttempts >= m_ReconnectMaxAttempts) {
        // 通知用户重连失败
        if (m_ConnectionCallback) {
            m_ConnectionCallback(ConnectionState::Failed, 
                "Maximum reconnection attempts reached (" + std::to_string(m_ReconnectMaxAttempts) + ")");
        }
        return;  // 已达到最大重连次数
    }
    
    if (!m_ReconnectThreadRunning) {
        // 尝试重新启动重连线程
        SetAutoReconnect(true);
        if (!m_ReconnectThreadRunning) {
            return;  // 重连线程无法启动
        }
    }
    
    // 计算重连延迟，最大限制在30秒
    uint32_t delay = m_ReconnectInitialDelay;
    for (uint32_t i = 0; i < m_ReconnectAttempts && delay < 30000; ++i) {
        delay *= 2;  // 指数退避
    }
    
    // 创建重连定时器
    if (!m_ReconnectTimer) {
        m_ReconnectTimer = std::make_unique<asio::steady_timer>(m_ReconnectIoContext);
    }
    
    m_ReconnectTimer->expires_after(std::chrono::milliseconds(delay));
    m_ReconnectTimer->async_wait([this](const asio::error_code& ec) {
        if (!ec) {
            // 尝试重连
            m_ReconnectAttempts++;
            
            // 通知用户正在尝试重连
            std::string attemptMessage = "Attempting to connect to " + m_Host + ":" + std::to_string(m_Port);
            if (m_ReconnectMaxAttempts > 0) {
                attemptMessage += " (Attempt " + std::to_string(m_ReconnectAttempts) + 
                                 " of " + std::to_string(m_ReconnectMaxAttempts) + ")";
            }
            
            if (m_ConnectionCallback) {
                m_ConnectionCallback(ConnectionState::Reconnecting, attemptMessage);
            }
            
            // 执行连接
            if (m_NetworkManager) {
                bool connected = m_NetworkManager->Connect(m_Host, m_Port);
                
                // 如果连接不成功，等待下一次重试
                if (!connected && m_AutoReconnect) {
                    // 如果仍在重试次数内或者允许无限重试，安排下一次重试
                    if (m_ReconnectMaxAttempts == 0 || m_ReconnectAttempts < m_ReconnectMaxAttempts) {
                        StartReconnect();
                    }
                }
            }
        }
    });
}

void NetworkClient::StopReconnect() {
    /* 功能：停止重连流程 */
    // 标记自动重连为关闭
    m_AutoReconnect = false;
    
    // 取消重连定时器
    if (m_ReconnectTimer) {
        asio::error_code ec;
        m_ReconnectTimer->cancel(ec);
    }
    
    // 停止重连线程
    if (m_ReconnectThreadRunning) {
        m_ReconnectThreadRunning = false;
        
        // 移除work以允许io_context退出run()
        if (m_ReconnectWork) {
            m_ReconnectWork.reset();
        }
        
        // 停止io_context
        try {
            m_ReconnectIoContext.stop();
        }
        catch (const std::exception&) {
            // 忽略io_context停止时的异常
        }
        
        // 安全地等待线程结束
        if (m_ReconnectThread.joinable()) {
            try {
                m_ReconnectThread.join();
            }
            catch (const std::exception&) {
                // 忽略线程join时的异常
            }
        }
    }
}

void NetworkClient::ReconnectThreadFunc() {
    /* 功能：重连线程函数 */
    try {
        while (m_ReconnectThreadRunning) {
            try {
                // 运行IO上下文直到没有更多工作或被停止
                m_ReconnectIoContext.run();
                
                // 如果io_context.run()返回，表示没有更多工作了
                break;
            }
            catch (const std::exception& e) {
                // 捕获并处理io_context运行期间的异常，继续循环
                if (!m_ReconnectThreadRunning) {
                    break;  // 如果线程已被标记为停止，则退出
                }
                
                // 短暂暂停后继续
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }
        }
    }
    catch (...) {
        // 捕获所有未知异常，防止线程崩溃
        m_ReconnectThreadRunning = false;
    }
    
    // 确保线程结束时标记为非运行状态
    m_ReconnectThreadRunning = false;
}

void NetworkClient::Update(float deltaTime) {
    m_DeltaTime += deltaTime;
    
    // 更新网络通道
    if (m_NetworkChannel) {
        m_NetworkChannel->Update();
    }
    
    // 更新定时器管理器
    if (m_TimerManager) {
        m_TimerManager->Update(m_DeltaTime);
    }
    
    // 每60秒记录一次内存池统计信息
    static float memoryStatTimer = 0.0f;
    memoryStatTimer += deltaTime;
    
    if (memoryStatTimer >= 60.0f) {
        std::string memoryStats = SeanNetwork::GetMemoryPoolStats();
        LOG_DEBUG("内存池定期统计: \n" + memoryStats);
        memoryStatTimer = 0.0f;
    }
    
    // 重置增量时间
    m_DeltaTime = 0.0f;
}

} // namespace SeanNetwork
